package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.DmcRfidReaderGroupBindMapper;
import com.csun.cmny.provider.dao.DmcRfidReaderGroupMapper;
import com.csun.cmny.provider.exceptions.DmcBizException;
import com.csun.cmny.provider.model.domain.DmcRfidReaderGroup;
import com.csun.cmny.provider.model.domain.DmcRfidReaderGroupAlarmLight;
import com.csun.cmny.provider.model.domain.DmcRfidReaderGroupBind;
import com.csun.cmny.provider.model.dto.rfid.RfidReaderDto;
import com.csun.cmny.provider.model.dto.rfid.RfidReaderGroupDto;
import com.csun.cmny.provider.model.dto.rfid.RfidReaderGroupQueryDto;
import com.csun.cmny.provider.model.enums.device.DmcDeviceTypeEnum;
import com.csun.cmny.provider.model.vo.rfid.DmcRfidReaderVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.DmcRfidReaderGroupAlarmLightService;
import com.csun.cmny.provider.service.DmcRfidReaderGroupBindService;
import com.csun.cmny.provider.service.DmcRfidReaderGroupService;
import com.csun.cmny.provider.service.DmcRfidReaderLocationService;
import com.csun.cmny.util.PublicUtil;
import com.github.pagehelper.PageHelper;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-08-22 15:05
 * @Description: the class dmc rfid reader group service impl
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class DmcRfidReaderGroupServiceImpl extends BaseService<DmcRfidReaderGroup>
        implements DmcRfidReaderGroupService {

    @Resource
    private CmnyMessageSource cmnyMessageSource;
    @Resource
    private DmcRfidReaderGroupMapper dmcRfidReaderGroupMapper;
    @Resource
    private DmcRfidReaderLocationService dmcRfidReaderLocationService;
    @Resource
    private DmcRfidReaderGroupBindMapper dmcRfidReaderGroupBindMapper;
    @Resource
    private DmcRfidReaderGroupBindService dmcRfidReaderGroupBindService;
    @Resource
    private DmcRfidReaderGroupAlarmLightService dmcRfidReaderGroupAlarmLightService;

    /**
     * add rfid reader group with rfid reader bind
     *
     * @param rfidReaderGroupDto the rfid reader group dto
     * @param loginAuthDto       the login auth dto
     *
     * @return the int
     */
    @Override
    public Integer addWithRfidReader(RfidReaderGroupDto rfidReaderGroupDto, LoginAuthDto loginAuthDto) {

        // 校验门禁组名称不能为空
        Preconditions.checkArgument(PublicUtil.isNotEmpty(rfidReaderGroupDto.getRfidReaderGroupName()),
                cmnyMessageSource.getMessage("rfid.reader.group.name.null", null));

        DmcRfidReaderGroup dmcRfidReaderGroup = new DmcRfidReaderGroup();
        dmcRfidReaderGroup.setRfidReaderGroupName(rfidReaderGroupDto.getRfidReaderGroupName());
        dmcRfidReaderGroup.setRemark(rfidReaderGroupDto.getRemark());
        dmcRfidReaderGroup.setGroupId(loginAuthDto.getGroupId());
        dmcRfidReaderGroup.setUpdateInfo(loginAuthDto);
        Integer result = dmcRfidReaderGroupMapper.insertSelective(dmcRfidReaderGroup);
        if (result < 1) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064001);
        }

        // 校验门禁读卡器列表不能为空
        Preconditions.checkArgument(PublicUtil.isNotEmpty(rfidReaderGroupDto.getRfidReaderGroupList())
                        && rfidReaderGroupDto.getRfidReaderGroupList().size() == 2,
                cmnyMessageSource.getMessage("rfid.reader.list.null", null));

        List<DmcRfidReaderGroupBind> dmcRfidReaderGroupBindList = Lists.newArrayList();
        HashSet<Long> rfidReaderIdList = new HashSet<>();

        // 遍历门禁读卡器是否存在 是否绑定位置
        rfidReaderGroupDto.setId(dmcRfidReaderGroup.getId());
        checkRfidReaderList(rfidReaderGroupDto, dmcRfidReaderGroupBindList, rfidReaderIdList);

        // 判断两个门禁读卡器是否重复
        if (rfidReaderIdList.size() != 2) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064002);
        }

        /**
         * @date    2019-12-11
         * @author  chisj
         * @desc    门禁组中，门禁一是唯一的，门禁二可以在多个门禁组中（门禁二）.
         *          修复bug #4364
         */
        for (RfidReaderDto rr : rfidReaderGroupDto.getRfidReaderGroupList()) {
            if (rr.getNumber().equals(0)) { // 门禁一
                // 校验唯一
                int count = dmcRfidReaderGroupBindMapper.selectCountByRfidReaderIdList(Lists.newArrayList(rr.getDeviceId()));
                if (count > 0) {
                    throw new DmcBizException(ErrorCodeEnum.DMC10064003);
                }
            }
            if (rr.getNumber().equals(1)) { // 门禁二
                // 不能是已经是门禁一
                DmcRfidReaderGroupBind dmcRfidReaderGroupBind = new DmcRfidReaderGroupBind();
                dmcRfidReaderGroupBind.setRfidReaderId(rr.getDeviceId());
                dmcRfidReaderGroupBind.setNumber(0);
                int count = dmcRfidReaderGroupBindMapper.selectCount(dmcRfidReaderGroupBind);
                if (count > 0) {
                    throw new DmcBizException(ErrorCodeEnum.DMC10064008);
                }
            }
        }

        // 判断门禁读卡器是否已经被门禁组绑定
//        List<Long> list = Lists.newArrayList();
//        for (Long id : rfidReaderIdList) {
//            list.add(id);
//        }
//
//        int count = dmcRfidReaderGroupBindMapper.selectCountByRfidReaderIdList(list);
//        if (count > 0) {
//            throw new DmcBizException(ErrorCodeEnum.DMC10064003);
//        }

        result += dmcRfidReaderGroupBindService.batchSave(dmcRfidReaderGroupBindList);

        return result;
    }

    /**
     * edit rfid reader group with rfid reader bind
     *
     * @param rfidReaderGroupDto the rfid reader group dto
     * @param loginAuthDto       the login auth dto
     * @return the int.
     */
    @Override
    public Integer editWithRfidReader(RfidReaderGroupDto rfidReaderGroupDto, LoginAuthDto loginAuthDto) {

        Long rfidReaderGroupId = rfidReaderGroupDto.getId();
        Integer result = 0;

        // 门禁组Id不能为空
        Preconditions.checkArgument(PublicUtil.isNotEmpty(rfidReaderGroupId),
                cmnyMessageSource.getMessage("rfid.reader.group.id.null", null));

        DmcRfidReaderGroup dmcRfidReaderGroupQuery = dmcRfidReaderGroupMapper.selectByPrimaryKey(rfidReaderGroupId);
        if (dmcRfidReaderGroupQuery == null) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064004);
        }

        if (PublicUtil.isNotEmpty(rfidReaderGroupDto.getRfidReaderGroupName())) {
            dmcRfidReaderGroupQuery.setRfidReaderGroupName(rfidReaderGroupDto.getRfidReaderGroupName());
        }

        if (PublicUtil.isNotEmpty(rfidReaderGroupDto.getRemark())) {
            dmcRfidReaderGroupQuery.setRemark(rfidReaderGroupDto.getRemark());
        }

        dmcRfidReaderGroupQuery.setUpdateInfo(loginAuthDto);

        result = dmcRfidReaderGroupMapper.updateByPrimaryKeySelective(dmcRfidReaderGroupQuery);
        if (result < 1) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064005);
        }

        List<DmcRfidReaderGroupBind> dmcRfidReaderGroupBindList = Lists.newArrayList();
        HashSet<Long> rfidReaderIdList = new HashSet<>();

        // 校验门禁读卡器列表不能为空
        Preconditions.checkArgument(PublicUtil.isNotEmpty(rfidReaderGroupDto.getRfidReaderGroupList())
                        && rfidReaderGroupDto.getRfidReaderGroupList().size() == 2,
                cmnyMessageSource.getMessage("rfid.reader.list.null", null));

        checkRfidReaderList(rfidReaderGroupDto, dmcRfidReaderGroupBindList, rfidReaderIdList);

        // 判断两个门禁读卡器是否重复
        if (rfidReaderIdList.size() != 2) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064002);
        }

        DmcRfidReaderGroupBind dmcRfidReaderGroupBind = new DmcRfidReaderGroupBind();
        dmcRfidReaderGroupBind.setRfidReaderGroupId(rfidReaderGroupId);
        result += dmcRfidReaderGroupBindMapper.delete(dmcRfidReaderGroupBind);

        // 判断门禁读卡器是否已经被门禁组绑定
        List<Long> list = Lists.newArrayList();
        for (Long id : rfidReaderIdList) {
            list.add(id);
        }

        int count = dmcRfidReaderGroupBindMapper.selectCountByRfidReaderIdList(list);
        if (count > 0) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064003);
        }

        result += dmcRfidReaderGroupBindService.batchSave(dmcRfidReaderGroupBindList);

        return result;
    }

    public void checkRfidReaderList(RfidReaderGroupDto rfidReaderGroupDto, List<DmcRfidReaderGroupBind> dmcRfidReaderGroupBindList, HashSet<Long> rfidReaderIdList) {

        // 遍历门禁读卡器是否存在 是否绑定位置
        for (RfidReaderDto r : rfidReaderGroupDto.getRfidReaderGroupList()) {
            DmcRfidReaderVo dmcRfidReaderVo = dmcRfidReaderLocationService.selectByRfidReaderId(r.getDeviceId());
            if (PublicUtil.isEmpty(dmcRfidReaderVo)) {  // 判断门禁读卡器是否存在
                throw new DmcBizException(ErrorCodeEnum.DMC10063001);
            }
            if (PublicUtil.isEmpty(dmcRfidReaderVo.getLocation())) {    // 判断门禁读卡器是否绑定位置
                throw new DmcBizException(ErrorCodeEnum.DMC10063002);
            }
            if (!dmcRfidReaderVo.getDeviceType()
                    .equals(DmcDeviceTypeEnum.RFID_READER.getIndex())) {    // 判断设备是否为门禁读卡器
                throw new DmcBizException(ErrorCodeEnum.DMC10063003);
            }

            rfidReaderIdList.add(dmcRfidReaderVo.getId());

            DmcRfidReaderGroupBind dmcRfidReaderGroupBind = new DmcRfidReaderGroupBind();
            dmcRfidReaderGroupBind.setNumber(r.getNumber());
            dmcRfidReaderGroupBind.setRfidReaderId(dmcRfidReaderVo.getId());
            dmcRfidReaderGroupBind.setRfidReaderGroupId(rfidReaderGroupDto.getId());

            dmcRfidReaderGroupBindList.add(dmcRfidReaderGroupBind);
        }
    }

    /**
     * delete rfid reader group with rfid reader bind
     *
     * @param id the rfid reader group id
     * @return the int
     */
    @Override
    public Integer deleteWithRfidReaderById(Long id) {

        // 判断门禁组是否已经绑定报警灯
        DmcRfidReaderGroupAlarmLight dmcRfidReaderGroupAlarmLight = new DmcRfidReaderGroupAlarmLight();
        dmcRfidReaderGroupAlarmLight.setRfidReaderGroupId(id);
        int count = dmcRfidReaderGroupAlarmLightService.selectCount(dmcRfidReaderGroupAlarmLight);
        if (count > 0) {
            throw new DmcBizException(ErrorCodeEnum.DMC10064006);
        }

        // 删除门禁组信息
        Integer result = dmcRfidReaderGroupMapper.deleteByPrimaryKey(id);

        DmcRfidReaderGroupBind dmcRfidReaderGroupBind = new DmcRfidReaderGroupBind();
        dmcRfidReaderGroupBind.setRfidReaderGroupId(id);
        result += dmcRfidReaderGroupBindService.delete(dmcRfidReaderGroupBind);

        return result;
    }

    /**
     * query rfid reader group list with page
     *
     * @param rfidReaderGroupQueryDto the rfid reader group query dto
     *
     * @return the list.
     */
    @Override
    public List<RfidReaderGroupDto> queryListWithPage(RfidReaderGroupQueryDto rfidReaderGroupQueryDto) {

        int pageNum = rfidReaderGroupQueryDto.getPageNum();
        int pageSize = rfidReaderGroupQueryDto.getPageSize() * 2;
        PageHelper.startPage(pageNum, pageSize);

        return dmcRfidReaderGroupMapper.queryListWithPage(rfidReaderGroupQueryDto);
    }

    /**
     * query rfid reader group not bind alarm light
     *
     * @param groupId the group id
     *
     * @return the list
     */
    @Override
    public List<DmcRfidReaderGroup> queryNotBindAlarmLight(Long groupId) {

        return dmcRfidReaderGroupMapper.queryNotBindAlarmLight(groupId);
    }

    /**
     * select rfid reader group dto by rfid reader id
     *
     * @param rfidReaderId the rfid reader id
     *
     * @return the rfid reader group dto
     */
    @Override
    public RfidReaderGroupDto selectByRfidReaderId(Long rfidReaderId) {

        return dmcRfidReaderGroupMapper.selectByRfidReaderId(rfidReaderId);
    }
}
